package com.losalpes.catalog;

import com.losalpes.buy.IBuyService;
import com.losalpes.persistence.entity.Mueble;
import com.losalpes.persistence.entity.TipoMueble;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

/**
 *
 * @author Henry.Quiroga
 */
public class CatalogBean {

    @EJB
    private ICatalogService catalogService;
    @EJB
    private IBuyService buyService;
    private Mueble mueble = new Mueble(),  muebleBusqueda = new Mueble();
    private String mensaje = "",  noeliminar = "",  controlMensaje = "";
    private Date fechaInicioPromocion;
    private Date fechaFinPromocion;

    /**
     * Constructor de la clase
     */
    public CatalogBean() {
        muebleBusqueda.setReferencia("");
        muebleBusqueda.setTipo(TipoMueble.Seleccione);
        muebleBusqueda.setNombre("");
    }

    /**
     * obtiene la fecha inicial de la promocion
     * @return
     */
    public Date getFechaFinPromocion() {
        return fechaFinPromocion;
    }

    /**
     * Establece la fecha final de la promcion
     * @param mueble
     */
    public void setFechaFinPromocion(Date fechaFinPromocion) {
        this.fechaFinPromocion = fechaFinPromocion;
    }

    /**
     * obtiene la fecha final de la promocion
     * @return
     */
    public Date getFechaInicioPromocion() {
        return fechaInicioPromocion;
    }

    /**
     * Establece la fecha inicial de la promcion
     * @param mueble
     */
    public void setFechaInicioPromocion(Date fechaInicioPromocion) {
        this.fechaInicioPromocion = fechaInicioPromocion;
    }

    /**
     * obtiene el mueble actual
     * @return
     */
    public Mueble getMueble() {
        return mueble;
    }

    /**
     * Establece el mueble actual
     * @param mueble
     */
    public void setMueble(Mueble mueble) {
        this.mueble = mueble;
    }

    /**
     * Obtiene el mueble de busqueda actua;
     * @return
     */
    public Mueble getMuebleBusqueda() {
        return muebleBusqueda;
    }

    /**
     * Establece el mueble de busqueda actual
     * @param mueble
     */
    public void setMuebleBusqueda(Mueble mueble) {
        this.muebleBusqueda = mueble;
    }

    /**
     * obtiene el mensaje de control al querer eliminar un mueble
     * @return
     */
    public String getControlMensaje() {
        return controlMensaje;
    }

    /**
     * Establece el mensaje de control
     * @param controlMensaje
     */
    public void setControlMensaje(String controlMensaje) {
        this.controlMensaje = controlMensaje;
    }

    /**
     * Obtiene el mensaje a mostrar al usuario
     * @return
     */
    public String getMensaje() {
        return mensaje;
    }

    /**
     * Establece sl mensaje a mostrar al usuario
     * @param mensaje
     */
    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    /**
     * Obtiene el mensaje de eliminacion del mueble
     * @return
     */
    public String getNoeliminar() {
        return noeliminar;
    }

    /**
     * Establece el mensaje de eliminacion del mueble
     * @param noeliminar
     */
    public void setNoeliminar(String noeliminar) {
        this.noeliminar = noeliminar;
    }

    /**
     * Realiza una busqueda de los items del catalogo basado en un conjunto de restricciones
     * @return lista de productos coincidentes
     */
    public List getMuebles() {
        return catalogService.findMuebles(muebleBusqueda);
    }

    /**
     * Obtiene la lista de todos los productos de; catalogo
     * @return lista de productos
     */
    public List getProductos() {
        return catalogService.findAllMuebles();
    }

    /**
     * obtiene la lista de tipos de muebles
     * @return
     */
    public SelectItem[] getTiposMuebles() {
        return catalogService.getTiposMuebles();
    }

    /**
     * almacena un mueble
     * @return
     */
    public String save() {
        catalogService.save(mueble);
        return "lista";
    }

    /**
     * almacena un mueble y envia notificacion de promociones
     * @return
     */
    public String saveWithNotification() {
        mueble.setFechaInicioPromocion(new java.sql.Date(fechaInicioPromocion.getTime()));
        mueble.setFechaFinPromocion(new java.sql.Date(fechaFinPromocion.getTime()));
        catalogService.saveWithNotification(mueble);
        return "lista";
    }

    /**
     * Crea una nueva instancia del mueble en uso
     * @return string de navegacion
     */
    public String add() {
        mueble = new Mueble();
        return "detalle";
    }

    /**
     * Establece y clona el mueble actual para comenzar la edicion
     * @return
     */
    public String edit() {
        String id = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
        mueble = catalogService.getMueble(Long.parseLong(id));
        mueble = mueble.Clone();

        //Comentario de prueba para verificar
        if (mueble.getFechaInicioPromocion() != null) {
            fechaInicioPromocion = new Date(mueble.getFechaInicioPromocion().getTime());
        } else {
            fechaInicioPromocion = new Date();
        }
        if (mueble.getFechaFinPromocion() != null) {
            fechaFinPromocion = new Date(mueble.getFechaFinPromocion().getTime());
        } else {
            fechaFinPromocion = new Date();
        }


        return "detalle";
    }

    /**
     * Realiza la edicion para permitir agregar la promocion
     * @return
     */
    public String crearPromocion() {
        String id = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
        mueble = catalogService.getMueble(Long.parseLong(id));
        mueble = mueble.Clone();

        return "promocion";
    }

    /**
     * Permite establecer y navegar el detalle de un mueble seleccionado
     * @return
     */
    public String verDetalle() {
        String id = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
        mueble = catalogService.getMueble(Long.parseLong(id));
        return "detalle";
    }

    /**
     * Permite eliminar un mueble de la bd
     * @return
     */
    public String eliminar() {
        catalogService.delete(mueble);
        return "lista";
    }

    /**
     * Verifica si un mueble se puede eliminar
     * @return
     */
    public String delete() {
        if (!buyService.hayComprasMueble(mueble)) {
            mensaje = "Está seguro de eliminar el mueble con referencia  " + mueble.getReferencia() + " ?";
            noeliminar = "";
        } else {
            mensaje = "No es posible eliminar el mueble con referencia: " + mueble.getReferencia() + ", tiene compras realizadas";
            noeliminar = "visibility:hidden";
        }
        controlMensaje = "Cancelar";
        return "";
    }

    /**
     * Permite manejar facilmente la navagabilidad
     * @return
     */
    public String menu() {
        return (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("menu");
    }

    /**
     * Permite cargar una imagen
     * @param event
     * @throws java.io.IOException
     */
    public void subirArchivo(UploadEvent event) throws IOException {
        UploadItem item = event.getUploadItem();
        File file = item.getFile();

        InputStream fis = new FileInputStream(file);

        try {
            if (event == null) {
                return;
            }

            long length = file.length();
            if (length > Integer.MAX_VALUE) {
                throw new Exception("El archivo es demasiado grande");
            }

            // Create the byte array to hold the data
            byte[] bytes = new byte[(int) length];

            // Read in the bytes
            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
            }

            // Ensure all the bytes have been read in
            if (offset < bytes.length) {
                throw new IOException("Could not completely read file " + file.getName());
            }

            mueble.setFoto(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the input stream and return bytes
            fis.close();
        }
    }
}